package co.uk.j_wp.games.topdowngame.level;

import co.uk.j_wp.games.topdowngame.Game;
import co.uk.j_wp.games.topdowngame.Screen;
import co.uk.j_wp.games.topdowngame.entity.Entity;
import co.uk.j_wp.games.topdowngame.entity.Player;
import co.uk.j_wp.games.topdowngame.tile.Tile;

public class Level {
	public Tile[] tiles;
	private int tilesXCount;
	private int tilesYCount;
	private int xo = 0;
	private int yo = 0;

	private Player player;
	public Game game;

	

	public Level(Game g) {
		game = g;
	}

	public Level(Game g, LevelLoader levelLoader) {
		this(g);
		this.tilesXCount = levelLoader.getWidth();
		this.tilesYCount = levelLoader.getHeight();
		this.tiles = levelLoader.getTiles();
		{
			player = new Player(this);
			player.posx = levelLoader.getStartPosX();
			player.posy = levelLoader.getStartPosY();
		}
	}

	public Level levelInitMaze(int width, int height) {
		Generator gen = new Generator(width, height);
		{
			player = new Player(this);
			player.posx = (int) (Game.TILE_SIZE * 1.5f);
			player.posy = (int) (Game.TILE_SIZE * 0.5f);
		}
		tilesYCount = gen.getHeight();
		tilesXCount = gen.getWidth();

		byte[] maze = gen.generate();

		tiles = new Tile[tilesXCount * tilesYCount];
		for (int xy = 0; xy < tilesXCount * tilesYCount; xy++) {
			// Tile newTile = getTile1();
			Tile newTile;
			if (maze[xy] == Generator.PATH) {
				newTile = game.tiles.get(2, 0);
				newTile.setPassable(true);
				newTile.setColor(100);
			} else if (maze[xy] == Generator.START || maze[xy] == Generator.EXIT) {
				newTile = game.tiles.get(1, 0);
				newTile.setPassable(true);
				newTile.setColor(100);
			} else {
				newTile = game.tiles.get(0, 0);
				newTile.setPassable(false);
				newTile.setColor(50);
			}
			tiles[xy] = newTile;
		}
		return this;
	}

	private Tile getTile1() {
		return new Tile() {
			@Override
			public void draw(Screen s, Tile[] nextTiles, int xo, int yo) {
				s.setPixels(Game.TILE_SIZE, Game.TILE_SIZE, xo, yo, color);

				// boolean u = nextTiles[Tile.TILE_ABOVE] != null &&
				// nextTiles[Tile.TILE_ABOVE].color == color;
				// boolean d = nextTiles[Tile.TILE_BELOW] != null &&
				// nextTiles[Tile.TILE_BELOW].color == color;
				// boolean l = nextTiles[Tile.TILE_LEFT] != null &&
				// nextTiles[Tile.TILE_LEFT].color == color;
				// boolean r = nextTiles[Tile.TILE_RIGHT] != null &&
				// nextTiles[Tile.TILE_RIGHT].color == color;
				// if ((u || d) && !l && !r) {
				// s.setPixels(2, 16, xo + 7, yo, color + 10);
				// return;
				// }
				// if ((l || r) && !u && !d) {
				// s.setPixels(16, 2, xo, yo + 7, color + 10);
				// return;
				// }
				// if (l) {
				// s.setPixels(8, 2, xo, yo + 7, color + 10);
				// }
				// if (r) {
				// s.setPixels(8, 2, xo + 8, yo + 7, color + 10);
				// }
				// if (u) {
				// s.setPixels(2, 8, xo + 7, yo, color + 10);
				// }
				// if (d) {
				// s.setPixels(2, 8, xo + 7, yo + 8, color + 10);
				// }
			}
		};
	}

	public void draw(Screen s) {
		int startIndexX = 0;
		int startDrawX = xo;
		if (xo < 0) {
			startIndexX = -xo / Game.TILE_SIZE;
			startDrawX = xo % Game.TILE_SIZE;
		}
		int startIndexY = 0;
		int startDrawY = yo;
		if (yo < 0) {
			startIndexY = -yo / Game.TILE_SIZE;
			startDrawY = yo % Game.TILE_SIZE;
		}

		for (int y = 0; y < Game.SCREEN_SIZE_HEIGHT + 1; y++) {
			for (int x = 0; x < Game.SCREEN_SIZE_WIDTH + 1; x++) {
				int xi = x + startIndexX;
				int yi = y + startIndexY;
				Tile tile = getTile(xi, yi);
				if (tile != null) {
					Tile[] adjTiles = { getTile(xi, yi - 1), getTile(xi + 1, yi), getTile(xi, yi + 1), getTile(xi - 1, yi) };
					tile.draw(s, adjTiles, startDrawX + x * Game.TILE_SIZE, startDrawY + y * Game.TILE_SIZE);
				}
			}
		}
		if (isOnScreen(player))
			player.draw(s, -xo, -yo);
	}

	private boolean isOnScreen(Entity player) {
		// TODO Auto-generated method stub
		return true;
	}

	public Tile getTileAtCoords(int x, int y) {
		if (x > 0 && y > 0)
			return getTile((x / Game.TILE_SIZE), (y / Game.TILE_SIZE));
		else
			return null;
	}

	public Tile getTileAtCoords(float x, float y) {
		if (x > 0 && y > 0)
			return getTile((int) (x / Game.TILE_SIZE), (int) (y / Game.TILE_SIZE));
		else
			return null;
	}

	public void tick() {
		for (int xy = 0; xy < tilesXCount * tilesYCount; xy++) {
			getTile(xy % tilesXCount, xy / tilesYCount).tick();
		}
		player.tick();
		centerOnPlayer();
	}

	public void centerOn(Entity player) {
		this.xo = Game.SCREEN_OVERALL_WIDTH / 2 - (int) player.posx;
		this.yo = Game.SCREEN_OVERALL_HEIGHT / 2 - (int) player.posy;
	}

	public void centerOnPlayer() {
		centerOn(player);
	}

	public Level debug() {
		int xy = 0;
		for (int y = 0; y < tilesYCount; y++) {
			for (int x = 0; x < tilesXCount; xy++, x++) {
				System.out.print(tiles[xy].isPassable() ? "." : "#");
			}
			System.out.println("");
		}
		return this;
	}

	public Tile getTile(int x, int y) {
		if (x > -1 && x < tilesXCount && y > -1 && y < tilesYCount) {
			return tiles[tilesXCount * y + x];
		} else {
			return null;
		}
	}

	public int getTilesXCount() {
		return tilesXCount;
	}

	public int getTilesYCount() {
		return tilesYCount;
	}
}
